<template>
  <div class="wrap" :class="{ 'modal-wrap': formConfig.isInModal }">
    <div v-if="!formConfig.isInModal" class="page-btns-tab">
      <slot name="formHeader">
        <slot name="opreationBtns"></slot>
        <el-button
          v-if="getSaveBtnInfo.isShow ?? true"
          :disabled="getSaveBtnInfo.disabled"
          :loading="getSaveBtnInfo.isLoading || isLoading"
          type="primary"
          @click="onhandleSubmit"
        >
          {{ getSaveBtnInfo.name || "保存" }}
        </el-button>
        <el-button v-if="getBackBtnInfo.isShow ?? true" :disabled="getBackBtnInfo.disabled" plain @click="onhandleCancel">
          {{ getBackBtnInfo.name || "返回" }}
        </el-button>
      </slot>
    </div>
    <div class="form-wrap">
      <el-form
        ref="formRef"
        :disabled="formConfig.disabled"
        :label-position="formConfig.labelPosition || 'right'"
        :label-width="formConfig.labelWidth || '120px'"
        :model="form"
        :rules="formRules"
        :validate-on-rule-change="false"
      >
        <slot name="formBlock">
          <el-card :class="{ 'modal-card': formConfig.isInModal }" :shadow="formConfig.isInModal ? 'never' : 'always'">
            <template #header v-if="formConfig.title">
              {{ formConfig.title }}
              <slot name="cardHeaderBtn"></slot>
            </template>
            <slot name="cardSubHeader"></slot>
            <CommonFormItems
              v-model="form"
              :column-items="columnItems"
              :form-config-disabled="formConfig.disabled"
              :layout-config="layoutConfig"
              @on-handle-change-value="onHandleChangeValue"
            >
              <template v-for="(item, index) in getSlotColumns" :key="index" #[item.slotName]>
                <slot :name="item.slotName"></slot>
              </template>
            </CommonFormItems>
          </el-card>
        </slot>
        <slot></slot>
      </el-form>
    </div>
    <div v-if="formConfig.isInModal" class="page-btns-modal">
      <slot name="formFooter">
        <slot name="opreationBtns"></slot>
        <el-button
          v-if="getSaveBtnInfo.isShow ?? true"
          :disabled="getSaveBtnInfo.disabled"
          :loading="getSaveBtnInfo.isLoading || isLoading"
          type="primary"
          @click="onhandleSubmit"
        >
          {{ getSaveBtnInfo.name || "保存" }}
        </el-button>
        <el-button v-if="getBackBtnInfo.isShow ?? true" :disabled="getBackBtnInfo.disabled" plain @click="onhandleCancel">
          {{ getBackBtnInfo.name || "返回" }}
        </el-button>
      </slot>
    </div>
  </div>
</template>
<script>
import { useTabsStore } from "@/stores/modules/tabs";
import { TableColumnOrFormTypeEnum } from "@/plugins/commonType.enum.ts";
import CommonFormItems from "./CommonFormItems.vue";
import { postRequest } from "@/api/mains.ts";
// import { handleActivePath } from "@/utils/routes";
import { hODeepClone } from "@/utils/index";
import { useRoute, useRouter } from "vue-router";
import { succMsg, failMsg } from "@/utils/MessageUtils";
import { useKeepAliveStore } from "@/stores/modules/keepAlive";

export default defineComponent({
  name: "CommonForm",
  components: { CommonFormItems },
  props: {
    modelValue: {
      type: Object,
      default: () => {
        return {};
      }
    },
    layoutConfig: {
      type: Object,
      default: () => {
        return reactive({});
      }
    },
    option: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  emits: {
    "update:model-value": null,
    "on-extend-validate": null,
    "on-submit": null,
    "on-success": null,
    "on-cancel": null,
    "on-fail": null,
    "on-handle-submit": null,
    "on-pass-valid-result": null,
    "on-handle-change-value": null
  },
  setup(props, { emit, expose }) {
    const tabsStore = useTabsStore();
    // const { delVisitedRoute } = tabsStore;
    const route = useRoute();
    const router = useRouter();

    const keepAliveStore = useKeepAliveStore();

    //#endregion
    //#region  设计布局

    const isLoading = ref(false);
    const formRules = ref(props.option.rules);
    const formRef = ref(null);
    const {
      pageBtnTabPosition = ref("right"),
      pageBtnModalPosition = ref("center"),
      contentHeight = ref("100%")
    } = toRefs(props.layoutConfig);

    //#endregion

    //#region

    const form = ref(hODeepClone(props.modelValue));
    const { formConfig = {}, column: columnItems = [] } = props.option || {};

    /**
     * 获取column中的slot组合
     */
    const getSlotColumns = computed(() => {
      const { column: columnItems = [] } = props.option || {};
      return columnItems.filter(item => item.type === TableColumnOrFormTypeEnum.SLOT);
    });
    /**
     *
     * 保存按钮初始化
     */
    const getSaveBtnInfo = computed(() => {
      const { save } = props.option?.btnsConfig || {};
      return save || {};
    });

    /**
     * 返回按钮初始化
     */
    const getBackBtnInfo = computed(() => {
      const { back } = props.option?.btnsConfig || {};
      return back || {};
    });

    const onhandleSubmit = async () => {
      if (!formRef.value) return;
      const { isDoValidate = true, isOnlyNeedValidateResult = false } = props.option?.formConfig || {};
      if (!isDoValidate) {
        emit("on-handle-submit", formRef);
        return;
      }
      await formRef.value.validate((valid, fields) => {
        if (isOnlyNeedValidateResult) {
          emit("on-pass-valid-result", { valid, fields });
          return;
        }

        if (valid) {
          emit("on-extend-validate");
          const isValid = props.option.isValidatePass ?? true;
          if (isValid) {
            if (props.option.submitUrl) {
              isLoading.value = true;
              onHandleUpdate();
            } else {
              emit("on-submit");
            }
          }
        } else {
          failMsg("请完善表单");
          console.log("error submit!", fields);
        }
      });
    };

    const resetFields = () => {
      formRef.value.resetFields();
    };
    const onhandleCancel = () => {
      const { isInModal } = props.option.formConfig || {};
      if (isInModal) {
        emit("on-cancel");
      } else {
        goBack();
      }
    };

    async function onHandleUpdate() {
      const { submitUrl } = props.option;
      const res = await postRequest(submitUrl, form.value);
      isLoading.value = false;
      if (res.code == 200) {
        succMsg("操作成功");
        emit("on-success", res);
      } else {
        emit("on-fail", res);
      }
    }

    /**
     * 回退
     */
    const goBack = async () => {
      const { goBackPage } = props.option || {};
      if (goBackPage) {
        // const detailPath = await handleActivePath(route, true);
        // await router.push(goBackPage);
        // await delVisitedRoute(detailPath);

        tabsStore.removeTabs(route.fullPath);
        keepAliveStore.removeKeepAliveName(route.name);
        await router.push({ name: goBackPage /* , query: { refresh: true }  */ });
      } else {
        router.go(-1);
      }
    };

    /**
     * 改变值的回调
     */
    const onHandleChangeValue = params => {
      emit("on-handle-change-value", params);
    };

    //#region watch
    watch(
      () => ({ ...form.value }),
      newVal => {
        if (JSON.stringify(newVal) === JSON.stringify(props.modelValue)) return;
        emit("update:model-value", hODeepClone(form.value));
      },
      {
        deep: true
      }
    );

    watch(
      () => props.modelValue,
      newVal => {
        if (JSON.stringify(newVal) === JSON.stringify(form.value)) return;
        form.value = hODeepClone(newVal);
      },
      {
        deep: true
      }
    );

    watch(
      () => props.option.rules,
      newVal => {
        formRules.value = newVal;
      },
      {
        deep: true
      }
    );
    expose({ onhandleSubmit, onhandleCancel, resetFields, formRef });

    return {
      formConfig,
      getSaveBtnInfo,
      getBackBtnInfo,
      form,
      formRef,
      formRules,
      columnItems,
      getSlotColumns,
      pageBtnTabPosition,
      pageBtnModalPosition,
      contentHeight,
      isLoading,
      onhandleSubmit,
      onhandleCancel,
      onHandleChangeValue
    };
  }
});

//#endregion
</script>
<style lang="scss" scoped>
.wrap {
  width: 100%;
  &.modal-wrap {
    display: flex;
    flex-direction: column;
    height: v-bind(contentHeight);
    .form-wrap {
      flex: 1;
      height: 100%;
      overflow-y: auto;

      // overflow-y: auto;
    }
    .page-btns-modal {
      flex: 0 0 50px;
      padding-top: 15px;
      text-align: v-bind("pageBtnModalPosition");
    }
  }
  .page-btns-tab {
    display: flex;
    align-items: center;
    justify-content: v-bind("pageBtnTabPosition");
    padding: 10px;
    text-align: right;
    background-color: var(--el-bg-color);
    :deep() {
      .el-button {
        margin-left: 12px;
      }
    }
  }
  :deep() {
    .el-card {
      overflow: inherit;
    }
    .el-card__header {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
    .modal-card {
      border-width: 0;
      .el-card__body {
        padding: 20px 0 0;
      }
    }
  }
}
</style>
